package cn.com.aiton.trafficuser.controller;

import cn.com.aiton.common.model.ServiceResult;
import cn.com.aiton.common.model.UserDomain;
import cn.com.aiton.common.utils.JsonUtils;
import cn.com.aiton.common.utils.JwtUtil;
import cn.com.aiton.common.utils.ListBeanUtils;
import cn.com.aiton.trafficuser.service.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api/v1/user")
@CrossOrigin
public class UserController {
    private static final Logger LOG = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService service;
    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private MessageSource messageSource;
    Locale locale = LocaleContextHolder.getLocale();

    @RequestMapping({"findByUsername","/load/findByUsername"})
    @HystrixCommand(fallbackMethod = "findByUsernameFail")
    @ResponseBody
    public Object findByUsername(String username, HttpServletRequest request){

        ServiceResult<UserDomain> domain = service.findByUsername(username);
        Map<String,Object> msg = new HashMap<>();
        if (domain.isSuccess()){

            msg.put("code",0);
            msg.put("data",domain.getObject());
        }else{
            msg.put("code",-1);
            msg.put("data",null);
        }
        return msg;
    }
    public Object findByUsernameFail(String username, HttpServletRequest request){
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",-1);
        msg.put("msg",messageSource.getMessage("system.error.more.client",null,locale));

        //监控报警
        String findAllKye = "GpsController-findByIdFail";
        String sendValue = (String) redisTemplate.opsForValue().get(findAllKye);
        final String ip = request.getRemoteAddr();
        new Thread( ()->{
            if (StringUtils.isBlank(sendValue)) {
                LOG.warn(messageSource.getMessage("system.error.send.msg.warning",null,locale)+ip);
                //发送一个http请求，调用短信服务 TODO
                redisTemplate.opsForValue().set(findAllKye, "GpsController-findByIdFail", 20, TimeUnit.SECONDS);
            }else{
                LOG.warn(messageSource.getMessage("system.error.send.msg.20seconds",null,locale));
            }
        }).start();

        return msg;
    }


    @RequestMapping("findByUsernameAndPassword")
    @HystrixCommand(fallbackMethod = "findByUsernameAndPasswordFail")
    @ResponseBody
    public Object findByUsernameAndPassword(String username,String password, HttpServletRequest request){

        ServiceResult<UserDomain> domain = service.login(username,password);
        Map<String,Object> msg = new HashMap<>();
        if (domain.isSuccess()){
            msg.put("role","USER");
            msg.put("code",0);
            msg.put("msg","SUCCESS");
            msg.put("data",domain.getObject());
            String tok = JsonUtils.toJson(msg);
            String token = JwtUtil.createToken(null,UUID.randomUUID().toString(),tok);
            msg.put("token",token);
//            Cookie cookie = new Cookie(JwtUtil.JWT_AUTH,token);
//            cookie.setDomain("localhost");
//            cookie.setPath("/");

        }else{
            msg.put("code",-1);
            msg.put("data",null);
        }
        return msg;
    }
    public Object findByUsernameAndPasswordFail(String username,String password, HttpServletRequest request){
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",-1);
        msg.put("msg",messageSource.getMessage("system.error.more.client",null,locale));

        //监控报警
        String findAllKye = "GpsController-findByIdFail";
        String sendValue = (String) redisTemplate.opsForValue().get(findAllKye);
        final String ip = request.getRemoteAddr();
        new Thread( ()->{
            if (StringUtils.isBlank(sendValue)) {
                LOG.warn(messageSource.getMessage("system.error.send.msg.warning",null,locale)+ip);
                //发送一个http请求，调用短信服务 TODO
                redisTemplate.opsForValue().set(findAllKye, "GpsController-findByIdFail", 20, TimeUnit.SECONDS);
            }else{
                LOG.warn(messageSource.getMessage("system.error.send.msg.20seconds",null,locale));
            }
        }).start();

        return msg;
    }


    /**
     *

     * @param request
     * @return
     */
    @RequestMapping("save")
    @HystrixCommand(fallbackMethod = "saveFail")
    public Object save(String username, String password, Integer type, String phone, String address,  HttpServletRequest request) throws ParseException {
        String password1 = BCrypt.hashpw(password,BCrypt.gensalt());
        ServiceResult<UserDomain> domain = service.save(username,password1,type,phone,address, Calendar.getInstance().getTime());
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",0);
        msg.put("data",domain.getObject());
        return msg;
    }

    private Object saveFail(String username, String password, Integer type, String phone, String address,  HttpServletRequest request) throws ParseException {
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",-1);
        msg.put("msg",messageSource.getMessage("system.error.more.client",null,locale));
//监控报警
        String saveOrderKye = "GpsController-saveNodeFail";
        String sendValue = (String) redisTemplate.opsForValue().get(saveOrderKye);
        final String ip = request.getRemoteAddr();
        new Thread( ()->{
            if (StringUtils.isBlank(sendValue)) {
                LOG.warn(messageSource.getMessage("system.error.send.msg.warning",null,locale)+ip);
                //发送一个http请求，调用短信服务 TODO
                redisTemplate.opsForValue().set(saveOrderKye, "GpsController-saveNodeFail", 20, TimeUnit.SECONDS);
            }else{
                LOG.warn(messageSource.getMessage("system.error.send.msg.20seconds",null,locale));
            }
        }).start();
        return msg;
    }

    /**
     * 查询所有的用户
     * 只支持admin 查询这个方法
     *
     * @param request
     * @return
     */
    @RequestMapping("findAll")
    @HystrixCommand(fallbackMethod = "findAllFail")
    @PreAuthorize("hasAnyRole('vip')")
    public Object findAll(HttpServletRequest request){
        ServiceResult<List<UserDomain>> nodeDomains = service.findAll();
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",0);
        msg.put("data",nodeDomains.getObject());
        return msg;
    }
    public Object findAllFail(HttpServletRequest request){
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",-1);
        msg.put("msg",messageSource.getMessage("system.error.more.client",null,locale));

        //监控报警
        String findAllKye = "GpsController-findAll";
        String sendValue = (String) redisTemplate.opsForValue().get(findAllKye);
        final String ip = request.getRemoteAddr();
        new Thread( ()->{
            if (StringUtils.isBlank(sendValue)) {
                LOG.warn(messageSource.getMessage("system.error.send.msg.warning",null,locale)+ip);
                //发送一个http请求，调用短信服务 TODO
                redisTemplate.opsForValue().set(findAllKye, "GpsController-findAll", 20, TimeUnit.SECONDS);
            }else{
                LOG.warn(messageSource.getMessage("system.error.send.msg.20seconds",null,locale));
            }
        }).start();

        return msg;
    }



    @RequestMapping("findById")
    @HystrixCommand(fallbackMethod = "findByIdFail")
    public Object findById(Long id, HttpServletRequest request){
        ServiceResult<UserDomain> domain = service.findById(id);
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",0);
        msg.put("data",domain.getObject());
        return msg;
    }
    public Object findByIdFail(Long id, HttpServletRequest request){
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",-1);
        msg.put("msg",messageSource.getMessage("system.error.more.client",null,locale));

        //监控报警
        String findAllKye = "GpsController-findByIdFail";
        String sendValue = (String) redisTemplate.opsForValue().get(findAllKye);
        final String ip = request.getRemoteAddr();
        new Thread( ()->{
            if (StringUtils.isBlank(sendValue)) {
                LOG.warn(messageSource.getMessage("system.error.send.msg.warning",null,locale)+ip);
                //发送一个http请求，调用短信服务 TODO
                redisTemplate.opsForValue().set(findAllKye, "GpsController-findByIdFail", 20, TimeUnit.SECONDS);
            }else{
                LOG.warn(messageSource.getMessage("system.error.send.msg.20seconds",null,locale));
            }
        }).start();

        return msg;
    }

    @RequestMapping("update")
    @HystrixCommand(fallbackMethod = "updateFail")
    public Object update(Long id,String username, String password, Integer type, String phone, String address, HttpServletRequest request){
        ServiceResult<UserDomain> nodeDomains = service.update(id,username,password,type,phone,address,Calendar.getInstance().getTime());
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",0);
        msg.put("data",nodeDomains.getObject());
        return msg;
    }
    public Object updateFail(Long id,String username, String password, Integer type, String phone, String address, HttpServletRequest request){
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",-1);
        msg.put("msg",messageSource.getMessage("system.error.more.client",null,locale));

        //监控报警
        String findAllKye = "GpsController-updateFail";
        String sendValue = (String) redisTemplate.opsForValue().get(findAllKye);
        final String ip = request.getRemoteAddr();
        new Thread( ()->{
            if (StringUtils.isBlank(sendValue)) {
                LOG.warn(messageSource.getMessage("system.error.send.msg.warning",null,locale)+ip);
                //发送一个http请求，调用短信服务 TODO
                redisTemplate.opsForValue().set(findAllKye, "GpsController-updateFail", 20, TimeUnit.SECONDS);
            }else{
                LOG.warn(messageSource.getMessage("system.error.send.msg.20seconds",null,locale));
            }
        }).start();

        return msg;
    }

    @RequestMapping("delete")
    @HystrixCommand(fallbackMethod = "deleteFail")
    public Object delete(Long id, HttpServletRequest request){
        ServiceResult<UserDomain> result = service.delete(id);
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",0);
        msg.put("data","ID为"+id+"的节点删除成功");
        return msg;
    }
    public Object deleteFail(Long id, HttpServletRequest request){
        Map<String,Object> msg = new HashMap<>();
        msg.put("code",-1);
        msg.put("msg",messageSource.getMessage("system.error.more.client",null,locale));

        //监控报警
        String findAllKye = "GpsController-deleteFail";
        String sendValue = (String) redisTemplate.opsForValue().get(findAllKye);
        final String ip = request.getRemoteAddr();
        new Thread( ()->{
            if (StringUtils.isBlank(sendValue)) {
                LOG.warn(messageSource.getMessage("system.error.send.msg.warning",null,locale)+ip);
                //发送一个http请求，调用短信服务 TODO
                redisTemplate.opsForValue().set(findAllKye, "GpsController-deleteFail", 20, TimeUnit.SECONDS);
            }else{
                LOG.warn(messageSource.getMessage("system.error.send.msg.20seconds",null,locale));
            }
        }).start();

        return msg;
    }
}
